package com.nnnu.wsnackshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nnnu.wsnackshop.exception.ObjectException;
import com.nnnu.wsnackshop.mapper.PermissionsMapper;
import com.nnnu.wsnackshop.mapper.RolePermissionsMapper;
import com.nnnu.wsnackshop.pojo.dto.AddRoleDTO;
import com.nnnu.wsnackshop.pojo.dto.RolePageDTO;
import com.nnnu.wsnackshop.pojo.dto.UpdateRoleDTO;
import com.nnnu.wsnackshop.pojo.entity.Permissions;
import com.nnnu.wsnackshop.pojo.entity.RolePermissions;
import com.nnnu.wsnackshop.pojo.entity.Roles;
import com.nnnu.wsnackshop.mapper.RolesMapper;
import com.nnnu.wsnackshop.pojo.vo.RoleVO;
import com.nnnu.wsnackshop.result.PageResult;
import com.nnnu.wsnackshop.service.IRolesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统角色表 服务实现类
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@Service
@RequiredArgsConstructor
public class RolesServiceImpl extends ServiceImpl<RolesMapper, Roles> implements IRolesService {
    private final RolesMapper roleMapper;
    private final RolePermissionsMapper rpMapper;
    private final PermissionsMapper permissionMapper;

    @Override
    public PageResult<?> pageRoles(@NotNull RolePageDTO dto) {
        Page<Roles> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        Page<Roles> result = roleMapper.selectPage(page,
                new LambdaQueryWrapper<Roles>()
                        .like(StrUtil.isNotBlank(dto.getName()), Roles::getName, dto.getName())
        );

        List<RoleVO> vos = result.getRecords().stream().map(role -> {
            RoleVO vo = BeanUtil.copyProperties(role, RoleVO.class);

            // 查询该角色关联的权限
            Set<Permissions> permissions = permissionMapper.selectByRoleId(Long.valueOf(role.getId()));
            if (permissions != null && !permissions.isEmpty()) {
                vo.setPermissionIds(permissions.stream().map(Permissions::getId).collect(Collectors.toSet()));
                vo.setPermissionNames(permissions.stream().map(Permissions::getName).collect(Collectors.toSet()));
            } else {
                vo.setPermissionIds(Collections.emptySet());
                vo.setPermissionNames(Collections.emptySet());
            }

            return vo;
        }).collect(Collectors.toList());

        return PageResult.<RoleVO>builder()
                .total(result.getTotal())
                .items(vos)
                .build();
    }


    @Override
    public RoleVO getRoleDetail(Long id) {
        Roles role = roleMapper.selectById(id);
        if (role == null) throw new ObjectException("角色不存在");
        // 加载关联权限
        Set<Permissions> perms = permissionMapper.selectByRoleId(id);
        RoleVO vo = BeanUtil.copyProperties(role, RoleVO.class);
        vo.setPermissionIds(perms.stream().map(Permissions::getId).collect(Collectors.toSet()));
        vo.setPermissionNames(perms.stream().map(Permissions::getName).collect(Collectors.toSet()));
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRole(AddRoleDTO dto) {
        Roles role = BeanUtil.copyProperties(dto, Roles.class);
        roleMapper.insert(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(@NotNull UpdateRoleDTO dto) {
        Roles role = roleMapper.selectById(dto.getId());
        if (role == null) throw new ObjectException("角色不存在");
        role.setName(dto.getName());
        role.setDescription(dto.getDescription());
        roleMapper.updateById(role);

        // 更新角色-权限关联
        rpMapper.delete(new LambdaQueryWrapper<RolePermissions>().eq(RolePermissions::getRoleId, dto.getId()));
        if (dto.getPermissionIds() != null && !dto.getPermissionIds().isEmpty()) {
            dto.getPermissionIds().forEach(pid -> rpMapper.insert(new RolePermissions().setRoleId(Math.toIntExact(dto.getId())).setPermissionId(Math.toIntExact(pid))));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRoles(@NotNull List<Long> ids) {
        // 校验
        List<Long> missing = ids.stream().distinct().filter(id -> roleMapper.selectById(id) == null).toList();
        if (!missing.isEmpty()) {
            throw new ObjectException("角色不存在: " + missing);
        }
        // 删除关联
        rpMapper.delete(new LambdaQueryWrapper<RolePermissions>().in(RolePermissions::getRoleId, ids));
        // 删除角色
        roleMapper.deleteBatchIds(ids);
    }
}
